﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace PPIDesktopClient.General
{
    public abstract class Process
    {
        protected BackgroundWorker m_ProcessWorker;

        public Process()
        {
            m_ProcessWorker = new BackgroundWorker();
            m_ProcessWorker.WorkerReportsProgress = true;
            m_ProcessWorker.WorkerSupportsCancellation = true;
            m_ProcessWorker.DoWork += new DoWorkEventHandler(m_ProcessWorker_DoWork);
            m_ProcessWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(m_ProcessWorker_RunWorkerCompleted);
            m_ProcessWorker.ProgressChanged += new ProgressChangedEventHandler(m_ProcessWorker_ProgressChanged);

        }

        public virtual void StartProcess()
        {
            if (!m_ProcessWorker.IsBusy)
            {
                m_ProcessWorker.RunWorkerAsync();
            }
        }

        public void StopProcess()
        {
            m_ProcessWorker.CancelAsync();
        }

        protected int CalculateProgress(int amount, int total)
        {
            int _Progress;
            try
            {
                _Progress = (amount * 100) / total;
            }
            catch (Exception)
            {
                _Progress = 0;
            }
            return _Progress;
        }

        protected virtual void Work()
        {
        
        }

        protected virtual void EndWork()
        {
        }

        #region Worker Events
        
        private void m_ProcessWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            OnSaveProgressChanged(sender, e);
        }

        private void m_ProcessWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Cancelled)
            {
                OnSaveCancelled(sender, e);
            }
            else
            {
                EndWork();
                OnSaveCompleted(sender, e);
            }
        }

        private void m_ProcessWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (m_ProcessWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
            else
            {
                Work();
            }
            
        }

        #endregion

        #region Process Events
        public event EventHandler<ProgressChangedEventArgs> SaveProgressChanged;
        protected void OnSaveProgressChanged(object o, ProgressChangedEventArgs e)
        {
            // Safely invoke an event:
            if (SaveProgressChanged != null)
            {
                SaveProgressChanged(o, e);
            }
        }

        public event EventHandler SaveCompleted;
        protected void OnSaveCompleted(object o, EventArgs e)
        {
            // Safely invoke an event:
            if (SaveCompleted != null)
            {
                SaveCompleted(o, e);
            }
        }

        public event EventHandler SaveCancelled;
        protected void OnSaveCancelled(object o, EventArgs e)
        {
            // Safely invoke an event:
            if (SaveCancelled != null)
            {
                SaveCancelled(o, e);
            }
        }

        #endregion

    }
}
